import { useWebControlsStore } from '@/store/web/controls'
import { defineStore, acceptHMRUpdate } from 'pinia'
import { isHasOwnProperty, EventBus } from '@/utils'
import { EVENT_HOVER_TYPES, COMPONENT_TYPES, MOBILE_WID_HEI } from '@/const'
import { EVENT_ATTR, ROTATE3D_LIST, INTERACTION_DATA } from '@/const/web/'
import { getComponentDataByCid , searchComponentDataById } from '@/store/utils/'
import { WebTabName, WebRightMenu } from '../models/web/web-component'
import { dealVoteList } from './controls'
import { useWebPageStore } from './page'
import { useWebSiteStore } from './site'
import { ADD_COMP_ATTR } from '@/store/models/component-default-data'
import { guid } from '@/utils/'
import { WebSelectEvent, WebSelectAnimate } from '../models/web/web-page'
import { copyGroupComponentControls, addComponentData, deleteComponentControl } from '@/store/utils/web/'

export const useWebComponentStore = defineStore('webComponent', {
  state: (): IWebComponentStore => {
    return {
      currentComponentData: null,
      tabNames: new WebTabName(),
      rightMenu: new WebRightMenu(),
      selectEvent: new WebSelectEvent(),
      selectAnimate: new WebSelectAnimate(),
    }
  },
  getters: {
    isWbEvent(): boolean {
      let isWb = false;
      if (this.currentComponentData) {
        _.forEach(this.currentComponentData.events, (event: IEvent) => {
          if (event.controlId && event.controlId.length > 0) {
            isWb = true;
          }
        })
      }
      return isWb
    },
  },
  actions: {
    setRightMenuStatus(data: IWebRightMenu) {
      _.merge(this.rightMenu, data)
    },
    changeWH({width, height}: {width: number, height: number}) {
      if (this.currentComponentData) {
        this.currentComponentData.conAttr.width = _.parseInt(width)
        this.currentComponentData.conAttr.height = _.parseInt(height)
      }
    },
    adjustComponentZIndex(zIndex: number) {
      if (this.currentComponentData) {
        const useWebSite = useWebSiteStore()
        this.currentComponentData.conAttr.zIndex = zIndex
        useWebSite.siteStatus.zIndex = zIndex
      }
    },
    recordMousePosition(position: IWebPosition) {
      const useWebSite = useWebSiteStore()
      if(isHasOwnProperty(position, 'left')) {
        useWebSite.position.left = position.left
        useWebSite.position.top = position.top
      }
      const componentData = this.currentComponentData
      if (componentData) {
        _.merge(componentData.conAttr, position)
      }
    },
    setActiveComponentId(id?: string) {
      this.setActiveComponentId_(id)
      const componentData = this.currentComponentData
      const useWebControls = useWebControlsStore()
      const useWebPage = useWebPageStore()
      const useWebSite = useWebSiteStore()
      useWebControls.setActiveWbData(componentData ? componentData : useWebPage.currentPage)
      this.changeSelectEventPlane({ isActive: false, type: '' })
      this.changeSelectAnimatePlane({ isActive: false })
    },
    setActiveComponentId_(id?: string) {
      const useWebPage = useWebPageStore()
      let componentData_: IComponent | any
      if (!useWebPage.currentPage) {
        return
      }
      const useWebSite = useWebSiteStore()
      const useWebComponent = useWebComponentStore()
      if(id) {
        componentData_ = searchComponentDataById(id, useWebPage.currentPage)
      }
      _.forEach(useWebPage.currentPage.components, (compData: IComponent) => {
        if(componentData_ && componentData_.id == compData.id) {
          compData.active = true
          if (useWebSite.siteStatus.isShift) {
            if (useWebSite.siteStatus.shiftComponents.indexOf(componentData_) === -1) {
              useWebSite.siteStatus.shiftComponents.push(componentData_)
            }
          }
          if (isHasOwnProperty(componentData_, 'tabName') && !useWebComponent.tabNames[componentData_.tabName]) {
            useWebComponent.tabNames[componentData_.tabName] = 'tab-0'
          }
        } else {
          if (!useWebSite.siteStatus.isShift) {
            compData.active = false
          }
        }
      })
      useWebComponent.currentComponentData = componentData_
      if (!useWebComponent.currentComponentData || !useWebSite.siteStatus.isShift) {
        while (useWebSite.siteStatus.shiftComponents.length > 0) {
          useWebSite.siteStatus.shiftComponents.pop()
        }
      } else {
        let top = useWebComponent.currentComponentData.conAttr.top
        let left = useWebComponent.currentComponentData.conAttr.left
        useWebSite.position.top = top
        useWebSite.position.left = left
      }
    },
    isGroupCurrentComponent(isGroup: boolean) {
      const useWebSite = useWebSiteStore()
      const useWebPage = useWebPageStore()
      const useWebControl = useWebControlsStore()
      //坐标系转换
      const shiftComponents = useWebSite.siteStatus.shiftComponents
      if (isGroup) {
        if (shiftComponents.length < 1) {
          return
        }
        let comps: IComponent = _.cloneDeep(shiftComponents)
        let len = comps.length
        let comp: IComponent
        let minxs: number[] = []
        let maxxs: number[] = []
        let minys: number[] = []
        let maxys: number[] = []
        let minx = 0
        let maxx = 0
        let miny = 0
        let maxy = 0
        let i = 0
        for (i = 0; i < len; i++) {
          comp = comps[i]
          minxs.push(comp.conAttr.left)
          maxxs.push(comp.conAttr.left + comp.conAttr.width)
          minys.push(comp.conAttr.top)
          maxys.push(comp.conAttr.top + comp.conAttr.height)
        }
        minx = _.min(minxs)
        maxx = _.max(maxxs)
        miny = _.min(minys)
        maxy = _.max(maxys)
        for (i = 0; i < len; i++) {
          comp = comps[i]
          comp.conAttr.left -= minx
          comp.conAttr.top -= miny
        }
        const newGroupComponent = _.cloneDeep(getComponentDataByCid(COMPONENT_TYPES.group_component))
        const addCompAttr = _.cloneDeep(ADD_COMP_ATTR)
        delete addCompAttr.conStyles
        _.merge(newGroupComponent, addCompAttr)
        newGroupComponent.conAttr.width = maxx - minx
        newGroupComponent.conAttr.height = maxy - miny
        newGroupComponent.conAttr.left = minx
        newGroupComponent.conAttr.top = miny
        newGroupComponent.id = guid()
        newGroupComponent.components = _.concat(newGroupComponent.components, comps)
        newGroupComponent.conAttr.zIndex = useWebSite.siteStatus.zIndex
        newGroupComponent.active = true
        useWebSite.removeShiftComponents()
        useWebPage.addComponent_(newGroupComponent)
        this.setActiveComponentId_(newGroupComponent.id)
        useWebSite.siteStatus.isShift = false
      } else {
        if (this.currentComponentData && this.currentComponentData.components && this.currentComponentData.components.length > 0) {
          const componentData = this.currentComponentData
          const comps = componentData.components
          this.removeCurrentComponent_()
          this.setActiveComponentId_()
          useWebControl.deleteControl(componentData.id)
          useWebControl.setActiveWbData(null)
          let comp: any | IComponent
          for (let i = 0, len = comps.length; i < len; i++) {
            comp = comps[i]
            comp.conAttr.left += componentData.conAttr.left
            comp.conAttr.top += componentData.conAttr.top
            useWebPage.addComponent_(comp)
            this.setActiveComponentId_(comp.id)
            if (_.size(comp.events) > 0) {
              for (let key in comp.events) {
                let event = comp.events[key]
                if (event.controlId && event.controlId.length > 0) {
                  useWebControl.setActiveWbData(comp)
                  break
                }
              }
            }
          }
        }
      }
    },
    copyCurrentComponent () {
      const componentData = _.cloneDeep(this.currentComponentData)
      //对于打组的组件进行处理
      if(componentData.components && componentData.components.length > 0) {
        copyGroupComponentControls(componentData)
      }
      const compId: string = guid()
      const copyId: string = componentData.id
      componentData.id = compId
      const useWebSite = useWebSiteStore()
      const useWebControls = useWebControlsStore()
      useWebSite.componentMap[componentData.id] = componentData
      useWebControls.addEventControlToControls({ copyId, compId })
  
      componentData.conAttr.top += 40
      addComponentData(componentData)
    },
    replaceCurrentComponentData(compData: IComponent) {
      _.merge(this.currentComponentData, compData)
      EventBus.$emit('refreshCommonAttr')
    },
    removeCurrentComponent () {
      const useWebSite = useWebSiteStore()
      const useWebComponent = useWebComponentStore()
      const useWebControls = useWebControlsStore()
      const componentData = useWebComponent.currentComponentData
      if(useWebSite.siteStatus.isEdit || !componentData) {
        return
      }
      // 更新 底部菜单 isTab，为 true 则 禁用滑动翻页
      // if(COMPONENT_TYPES.wb_menu == componentData.cid) {
      //   useWebSite.setIfTab(false)
      // }
      this.removeCurrentComponent_()
      useWebComponent.setActiveComponentId_()
      useWebControls.deleteControl(componentData.id)
      delete useWebSite.componentMap[componentData.id]
      if(componentData.components && componentData.components.length > 0){
        deleteComponentControl(componentData)
      }
      useWebControls.setActiveWbData(null)
    },
    singleAlignComponents() {
      const componentData = this.currentComponentData;
      if(componentData) {
        const left = _.parseInt((MOBILE_WID_HEI.width - componentData.conAttr.width)/2)
        componentData.conAttr.left = left
      }
    },
    updateTab(data: IWebTabName | any) {
      for (let key in data) {
        this.tabNames[key] = data[key]
      }
    },
    deactiveCurrentComponent() {
      if (this.currentComponentData) {
        this.currentComponentData.active = false
      }
    },
    updateCurrentComponentData(data: IComponent | any) {
      const useWebPage = useWebPageStore()
      if (data.dataKeys && !isHasOwnProperty(this.currentComponentData, 'dataKeys')) {
        this.currentComponentData!['dataKeys'] = data.dataKeys
      }
      if (!isHasOwnProperty(useWebPage.componentFrontAttr, data.id)) {
        useWebPage.componentFrontAttr[data.id] = { isHidden: false, isLock: false }
      }
      _.merge(this.currentComponentData, data)

      EventBus.$emit('refreshCommonAttr', this.currentComponentData!.id)
    },
    updateAnimateAttr(data: IAnimation | any) {
      if (!this.currentComponentData) {
        return
      }
      _.merge(this.currentComponentData.animate, data)
    },
    changeSelectAnimatePlane({ isActive, index = -1 }: { isActive: boolean, index?: number }) {
      this.selectAnimate.isActive = isActive
      this.selectAnimate.index = index
    },
    addAnimate(item: ICssAnimation) {
      this.currentComponentData!.animate!.animates.push(item)
    },
    updateCurrentAnimateItem(item: ICssAnimation | any) {
      this.currentComponentData!.animate!.isPlayAll = false;
      const playAnimateIndex = this.currentComponentData!.animate!.playAnimateIndex
      _.merge(this.currentComponentData!.animate!.animates[playAnimateIndex], item)
    },
    deleteAnimate(index: number) {
      this.currentComponentData!.animate!.isPlayAll = false
      this.currentComponentData!.animate!.animates.splice(index, 1)
    },
    playAnimateAll(isPlayAll: boolean) {
      this.currentComponentData!.animate!.isPlayAll = isPlayAll
      const items = this.currentComponentData!.animate!.animates
      for (let key in items) {
        items[key].isPlaying = isPlayAll
      }
    },
    updateAnimateIndex(index: number) {
      this.currentComponentData!.animate!.isPlayAll = false
      this.currentComponentData!.animate!.playAnimateIndex = index
    },
    updateAnimateByIndex({ index = -1, item, triggerType = -1 }: { index?: number, item?: ICssAnimation, triggerType?: number }) {
      if (!this.currentComponentData || !this.currentComponentData.animate) {
        return
      }
      this.currentComponentData.animate.isPlayAll = false
      if(index >= 0) {
        _.merge(this.currentComponentData.animate.animates[index], item)
      }
      if (triggerType >= 0) {
        this.currentComponentData.animate.triggerType = triggerType
      }
    },
    updateInteractionData(interactionData: IInteractionData) {
      _.merge(this.currentComponentData!.interactionData, interactionData)
    },
    addInteractionItem({index, item}: {index: number, item: IInteractionItem}) {
      const interactionData = this.currentComponentData!.interactionData as IInteractionData
      if (interactionData.isDimension) {
        if (index >= 0) {
          interactionData.dimensionLists![index].push(item)
        } 
      } else {
        interactionData.lists.push(item)
      }
    },
    deleteInteractionItem({index, qIndex}: {index: number, qIndex: number}) {
      const interactionData = this.currentComponentData!.interactionData
      if (interactionData.isDimension) {
        if (qIndex >= 0) {
          interactionData.dimensionLists![index].splice(qIndex, 1)
        } else {
          interactionData.dimensionLists!.splice(index, 1)
        }
      } else {
        interactionData.lists.splice(index, 1)
      }
    },
    updateCurrentComponentDataDataKeys(dataKeys: Object) {
      this.currentComponentData!.dataKeys = dataKeys
    },
    generateQrcode(data: any) {
      this.currentComponentData!.commonAttr.url = data ? data.img_src : "";
    },
    changeSelectEventPlane({ isActive, type }: { isActive: boolean, type: string }) {
      this.selectEvent.isActive = isActive
      this.selectEvent.type = type
    },
    addEvent(event: IEvent)  {
      this.addEvent_(event)
      const componentData = this.currentComponentData
      const controlId = event.controlId
      const useWebControls = useWebControlsStore()
      if(controlId && controlId.length > 0) {
        useWebControls.setActiveWbData(componentData)
        useWebControls.addEventControlToCurrentControls(controlId)
      }
      useWebControls.dealVoteListCommit()
    },
    addEvent_(event: IEvent) {
      const componentData: IComponent = this.currentComponentData!
      event.index = _.size(componentData.events)
      componentData.events![event.type] = event
      
      if (event.controlId && event.controlId.length > 0) {
        if (!isHasOwnProperty(componentData, 'eventAttr')) {
          if(EVENT_ATTR[event.controlId]){
            const eventAttr = _.cloneDeep(EVENT_ATTR[event.controlId].wbAttr)
            componentData.eventAttr = eventAttr
          }
        }
      } else if (event.type == EVENT_HOVER_TYPES.rotate3d) {
        if (!isHasOwnProperty(componentData, 'lists')) {
          componentData.lists = _.cloneDeep(ROTATE3D_LIST)
        }
      } else if (event.type == EVENT_HOVER_TYPES.interactionData) {
        if (!isHasOwnProperty(componentData, 'interactionData')) {
          componentData.interactionData = _.cloneDeep(INTERACTION_DATA)
        }
      }
    },
    updateEvent({type, event}: {type: string, event: IEvent}) {
      _.merge(this.currentComponentData!.events![type], event)
    },
    changeEventIndex({ eventIndex }: { eventIndex: number }) {
      const events = this.currentComponentData!.events
      const tempArr = _.sortBy(events, (event: IEvent) => { return event.index })
      _.forEach(tempArr, (event_: IEvent, index: number) => {
        if (index == eventIndex) {
          event_.index = index - 1
        } else if (index == eventIndex - 1) {
          event_.index = index + 1
        }
      })
    },
    deleteEvent({ type, controlId }: { type: string, controlId: string }) {
      delete this.currentComponentData!.events[type]
      if (type == EVENT_HOVER_TYPES.rotate3d) {
        //@ts-ignore
        delete this.currentComponentData!.lists
      } else if (type == EVENT_HOVER_TYPES.interactionData) {
        //@ts-ignore
        delete this.currentComponentData!.interactionData
      }
      //从新设置index
      const events = this.currentComponentData!.events
      const tempArr = _.sortBy(events, (event: IEvent) => { return event.index })
      _.forEach(tempArr, (event: IEvent, index: number) => {
        event.index = index
      })

      if (_.size(events) === 0) {
        //@ts-ignore
        delete this.currentComponentData!.eventAttr
      }
    },
    removeCurrentComponent_() {
      const useWebPage = useWebPageStore()
      const index = _.indexOf(useWebPage.currentPage!.components, this.currentComponentData)
      if (index != -1) {
        useWebPage.currentPage!.components.splice(index, 1)
      }
    },
    addComponentItem(data: IListItem) {
      const componentData = this.currentComponentData!
      if (componentData.commonAttr.isShiftInArr) {
        componentData.lists!.unshift(data);
      } else {
        componentData.lists!.push(data);
      }
      dealVoteList()
    },
    deleteComponentItem({index}: {index: number}) {
      let componentData = this.currentComponentData!
      componentData.lists!.splice(index, 1)
      dealVoteList()
    },
    updateComponentItem({index, item}: {index: number, item: IListItem}) {
      _.merge(this.currentComponentData!.lists[index], item)
      // const lists = this.currentComponentData!.lists
      // const item_ = lists[index]
      // for (let key in item) {
      //   item_[key] = item[key]
      //   if (_.isArray(item[key])) {
      //     _.merge(item_[key], item[key])
      //   }
      // }
      dealVoteList()
    },
  },
})

if (import.meta.hot) {
  import.meta.hot!.accept(acceptHMRUpdate(useWebComponentStore, import.meta.hot))
}